import com.dmall.heap.MaxHeap;
import com.dmall.heap.MinHeap;
import org.junit.Test;

import java.util.Random;

public class Main {

    public static void main(String[] args) {
        int n = 1000000;

        Random random = new Random();
        Integer[] testData = new Integer[n];
        for(int i = 0 ; i < n ; i ++) {
            testData[i] = random.nextInt(Integer.MAX_VALUE);
        }

        double time1 = testHeap(testData, false);
        System.out.println("Without heapify: " + time1 + " s");

        double time2 = testHeap(testData, true);
        System.out.println("With heapify: " + time2 + " s");
    }

    private static double testHeap(Integer[] testData, boolean isHeapify) {

        long startTime = System.nanoTime();

        MaxHeap<Integer> maxHeap;
        if (isHeapify) {
            maxHeap = new MaxHeap<>(testData);
        } else {
            maxHeap = new MaxHeap<>();
            for(int num: testData) {
                maxHeap.add(num);
            }
        }

        int[] arr = new int[testData.length];
        for(int i = 0 ; i < testData.length ; i ++) {
            arr[i] = maxHeap.extractMax();
        }
        for(int i = 1 ; i < testData.length ; i ++) {
            if (arr[i - 1] < arr[i]) {
                throw new IllegalArgumentException("Error");
            }
        }
        System.out.println("Test MaxHeap completed.");

        long endTime = System.nanoTime();

        return (endTime - startTime) / 1000000000.0;
    }

    @Test
    public void testMaxHeap() {
        int n = 1000000;

        MaxHeap<Integer> maxHeap = new MaxHeap<>();
        Random random = new Random();
        for(int i = 0 ; i < n ; i ++) {
            maxHeap.add(random.nextInt(Integer.MAX_VALUE));
        }

        int[] arr = new int[n];
        for(int i = 0 ; i < n ; i ++) {
            arr[i] = maxHeap.extractMax();
        }

        for(int i = 1 ; i < n ; i ++) {
            if (arr[i - 1] < arr[i]) {
                throw new IllegalArgumentException("Error");
            }
        }
        System.out.println("Test MaxHeap completed.");
    }

    @Test
    public void test1() {
        MinHeap<Integer> minHeap = new MinHeap<>();
        minHeap.add(3);
        minHeap.add(6);
        minHeap.add(5);
        minHeap.add(2);
        minHeap.add(7);

        int size = minHeap.size();
        for (int i = 0; i < size; i++) {
            System.out.println(minHeap.extractMin());
        }
    }

    @Test
    public void test2() {
        MaxHeap<Integer> maxHeap = new MaxHeap<>();
        maxHeap.add(3);
        maxHeap.add(6);
        maxHeap.add(5);
        maxHeap.add(2);
        maxHeap.add(7);

        int size = maxHeap.size();
        for (int i = 0; i < size; i++) {
            System.out.println(maxHeap.extractMax());
        }
    }

    @Test
    public void testMinHeap() {
        int n = 1000000;

        MinHeap<Integer> minHeap = new MinHeap<>();
        Random random = new Random();
        for(int i = 0 ; i < n ; i ++) {
            minHeap.add(random.nextInt(Integer.MAX_VALUE));
        }

        int[] arr = new int[n];
        for(int i = 0 ; i < n ; i ++) {
            arr[i] = minHeap.extractMin();
        }

        for(int i = 1 ; i < n ; i ++) {
            if (arr[i - 1] > arr[i]) {
                throw new IllegalArgumentException("Error");
            }
        }
        System.out.println("Test MinHeap completed.");
    }
}
